home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource3
/
123_01
/
tr.c
< prev
next >
Wrap
Text File
|
1985-03-11
|
6KB
|
319 lines
/*
Transliteration filter
Adapted from Software Tools, by Kernighan & Plauger.
source: tr.c
version: February 22, 1983
Link this program to the directed I/O packages as follows:
A>clink tr -f dio
Transliterated from RATFOR to BDS C by:
Robert Pasky
36 Wiswall Rd
Newton, MA 02159
(617) 964-3641
Edited by:
Edward K. Ream
1850 Summit Ave.
Madison, WI 53705
(608) 231 - 2952
See the file tr.doc for complete documentation.
*/
#include "bdscio.h"
#include "dio.h"
#define MAXSET 129
#define NOTSYM '~'
#define ESCAPE '\\'
#define DASH '-'
#define UPPER 1
#define LOWER 0
#define YES 1
#define NO 2
/* comment out ----- remove this comment to get debugging messages
#define DEBUG 1
----- end comment out */
int casesw;
int ix, jx;
main(argc, argv)
int argc;
char **argv;
{
/* Set up the filter. */
_allocp = NULL;
dioinit(&argc, argv);
main1(argc, argv);
/* Indicate no error in the pipe. */
dioflush();
}
/* Main line. */
main1(argc, argv)
int argc;
char *argv[];
{
int c;
char from[MAXSET], to[MAXSET];
char *s;
int allbut, collap, i, lastto;
if (argc < 2) {
fprintf(STD_ERR,
"usage: tr <infile [>outfile] from [to]\n");
dioflush();
exit();
}
casesw = LOWER;
s = *++argv;
from[0] = NULL;
if (s[0] == NOTSYM) {
allbut = YES;
if (makset(s, 1, from) == NO) {
fprintf(STD_ERR, "<from> too large\n");
dioflush();
exit();
}
}
else {
allbut = NO;
if (makset(s, 0, from) == NO) {
fprintf(STD_ERR, "<from> too large\n");
dioflush();
exit();
}
}
#ifdef DEBUG
fprintf(STD_ERR, "from: <%s>\n", from);
#endif
casesw = LOWER;
s = *++argv;
to[0] = NULL;
if (argc <= 2 || s[0] == NULL) {
to[0] = NULL;
}
else if (makset(s, 0, to) == NO) {
fprintf(STD_ERR, "<to> too large\n");
dioflush();
exit();
}
#ifdef DEBUG
fprintf(STD_ERR, "to: <%s>\n", to);
#endif
lastto = strlen(to) - 1;
if (strlen(from) > (lastto + 1) || allbut == YES) {
collap = YES;
}
else {
collap = NO;
}
for(;;) {
c = getchar();
i = xindex(from, c, allbut, lastto);
if (collap == YES && i >= lastto && lastto >= 0) {
putchar(to[lastto]);
do {
c = getchar();
i = xindex(from, c, allbut, lastto);
} while (i >= lastto);
}
if (c == CPMEOF || c == EOF) {
break;
}
if (i >= 0 && lastto >= 0) {
putchar(to[i]);
}
else if (i == -1) {
putchar(c);
}
}
}
makset(array, k, set) /* make the from/to set from array */
int k;
char array[], set[];
{
ix = k;
jx = 0;
filset(NULL, array, set);
return (addset(NULL, set));
}
addset(c, set) /* add single code to set */
char c, set[];
{
if (jx > MAXSET)
return(NO);
set[jx++] = c;
return (YES);
}
filset(delim, array, set) /* fill set from array */
char delim, array[], set[];
{
char digits[11];
char lowalf[27];
char upalf[27];
char c;
strcpy(digits, "0123456789");
strcpy(lowalf, "abcdefghijlkmnopqrstuvwxyz");
strcpy(upalf, "ABCDEFGHIJLKMNOPQRSTUVWXYZ");
for ( ; array[ix] != delim && array[ix] != NULL; ix++) {
if (array[ix] == ESCAPE) {
if ((c = esc(array)) != NULL) {
addset(c, set);
}
}
else if (array[ix] != DASH) {
if (casesw == LOWER) {
array[ix] = tolower(array[ix]);
}
addset(array[ix], set);
}
else if (jx <= 0 || array[ix + 1] == NULL) {
addset(DASH, set);
}
else if (index(digits, set[jx - 1]) >= 0 ) {
dodash(digits, array, set);
}
else if (index(lowalf, set[jx - 1]) >= 0 ) {
dodash(lowalf, array, set);
}
else if (index(upalf, set[jx - 1]) >= 0 ) {
dodash(upalf, array, set);
}
else {
addset(DASH, set);
}
}
}
dodash(valid, array, set) /* parse intervals */
char valid[], array[], set[];
{
int k, limit;
ix++;
jx--;
limit = index(valid, esc(array));
for (k = index(valid, set[jx]); k <= limit; k++) {
addset(valid[k], set);
}
}
esc(array) /* handle escape sequences, returns intended code */
char array[];
{
int sum;
if (casesw == LOWER) {
array[ix] = tolower(array[ix]);
}
if (array[ix] != ESCAPE) {
return (array[ix]);
}
else if (array[ix + 1] == NULL) {
return (ESCAPE);
}
else {
ix++;
switch(tolower(array[ix])) {
case 'n':
return('\n');
case 't':
return('\t');
case 'b':
return(' ');
case 'r':
return('\r');
case 'l':
casesw = LOWER;
return (NULL);
case 'u':
casesw = UPPER;
return (NULL);
case '0': case '1':
case '2': case '3':
case '4': case '5':
case '6': case '7':
sum = array[ix] - '0';
while (isdigit(array[ix+1])) {
sum = sum * 8 + array[ix++] - '0';
}
return (sum & 0xff);
default:
if (casesw == LOWER) {
array[ix] = tolower(array[ix]);
}
return(array[ix]); /* takes care of ESCAPE ESCAPE */
}
}
}
xindex(array, c, allbut, lastto) /* return index of c
modified by allbut */
char array[], c;
int allbut, lastto;
{
int i;
if (c == NULL) {
return (-1);
}
else if (allbut == NO) {
return (index(array, c));
}
else if (index(array, c) >= 0) {
return (-1);
}
else {
return (lastto + 1);
}
}
index(s, c) /* return index of c in s */
char *s, c;
{
int i;
for (i = 0; s[i] != NULL; i++) {
if(s[i] == c) {
return (i);
}
}
return (-1);
}
/
char *s,